<!--
 * @Author: your name
 * @Date: 2021-07-28 11:55:42
 * @LastEditTime: 2021-08-12 20:30:23
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /shb-pc-fe/src/modules/productV2/productMenuView/components/CustomerBind.vue
-->
<template>
  <base-modal
    :title="$t('product.component.customerBind.title')"
    :show.sync="bindDialog"
    width="500px"
    class="customer-bind-dialog"
    @closed="reset"
     v-if="init"
  >
   <form-builder ref="form" :fields="bindFormFields"  mode="task" @update="update">
      <!-- start 客户字段 -->
      <template slot="customer" slot-scope="{ field }">
        
        <!-- start 客户 -->
        <form-item :label="field.displayName">
          <div class="input-and-btn">
            <biz-remote-select
              :value="value.customer"
              :field="customerField"
              :remote-method="searchCustomer"
              @input="updateCustomer"
              :cleared="true"
              :placeholder="$t('common.placeholder.searchCustomer')"
              :input-disabled="isCreateCustomer"
              :computed-width-keys="['name']"
            >
              <div class="customer-template-option" slot="option" slot-scope="{ option }">
                <h3>{{ option.name }}</h3>
                <p>
                  <span>
                    <label>{{ $t('common.form.type.phone') }}：</label>
                    <span>{{ option.lmPhone }}</span>
                  </span>
                  <span>
                    <label>{{ $t('common.form.type.serialNumber') }}：</label>
                    <span>{{ option.serialNumber }}</span>
                  </span>           
                </p>
              </div>
            </biz-remote-select>
            <el-button type="plain-third" @click="dialogOpen('customer')" v-if="allowCreateCustomer">{{ $t('common.base.create') }}</el-button>
          </div>
        </form-item>
        <!-- end 客户 -->

        <!-- start 联系人 -->
        <form-item v-if="customerOption.linkman" :label="$t('common.base.contact')">
          <div class="input-and-btn">
            <biz-remote-select
              ref="linkman"
              :placeholder="$t('common.form.placeHolder.linkman.pla1')"
              v-model="value.linkman"
              :cleared="true"
              :remote-method="searchLinkmanOuterHandler"
              :input-disabled="isCreateCustomer"
              @input="updateLinkman(value.linkman[0])"
              :computed-width-keys="['name']"
            >
            </biz-remote-select>
            <el-button type="plain-third" @click="dialogOpen('contact')" v-if="allowCreateLinkman">{{ $t('common.base.create') }}</el-button>
          </div>
        </form-item>
        <!-- end 联系人 -->

        <!-- start 地址 -->
        <form-item v-if="customerOption.address" :label="$t('common.form.type.address')">
          <div class="input-and-btn">
            <biz-remote-select
              ref="bizRemoteSelectAddress"
              v-model="value.address"
              :placeholder="$t('common.form.placeHolder.customerAddress.pla1')"
              :cleared="true"
              :remote-method="searchAddressOuterHandler"
              :computed-width-keys="['address']"
              :mounted-search="true"
            >
            </biz-remote-select>
            <el-button type="plain-third" @click="dialogOpen('address')" v-if="allowCreateCustomer">{{ $t('common.base.create') }}</el-button>
          </div>
        </form-item>
        <!-- end 地址 -->
      </template>
    </form-builder>
  
    <div slot="footer" class="dialog-footer">
      <el-button @click="bindDialog = false">{{ $t('common.base.cancel') }}</el-button>
      <el-button type="primary" @click="sumbit" :disabled="pending">{{ $t('common.base.save') }}</el-button>
    </div>

    <!-- start 新建客户弹窗 -->
    <base-modal :title="$t('product.component.customerBind.createCutomerTitle')" :show.sync="addCustomerDialog" class="add-dialog-container" width="800px" @closed="dislogClose('customer')">
      <div id="createCustomerView"></div>
      <div class="dialog-footer" slot="footer">
        <el-button @click="addCustomerDialog = false">{{ $t('common.base.close') }}</el-button>
        <el-button type="primary" @click="addCustomerSubmit">{{ $t('common.base.save') }}</el-button>
      </div>
    </base-modal>
    <!-- end 新建客户弹窗 -->

       <!-- start 联系人弹窗 -->
    <edit-contact-dialog ref="EditContactDialog" :customer="convertCustomerOfSelect(selectedCustomer)" :is-phone-unique="customerInitData.isPhoneUnique"/>
    <!-- end 联系人弹窗 -->

    <!-- start 地址弹窗 -->
    <edit-address-dialog ref="EditAddressDialog" :customer-id="selectedCustomer.id || selectedCustomer.value" :default-address="customerInitData.customerAddress"/>
    <!-- end 地址弹窗 -->
  </base-modal>
</template>

<script>
import _ from 'lodash'
/* components */
import EditAddressDialog from '@src/modules/customer/view/operationDialog/EditAddressDialog.vue'
import EditContactDialog from '@src/modules/customer/view/operationDialog/EditContactDialog.vue'
import { TaskFieldNameMappingEnum } from '@model/enum/FieldMappingEnum.ts'
import { getFieldValue2string } from '@service/TaskService.ts'
import methods from './methods'
import { 
  linkmanSelectConversion,
  customerAddressSelectConversion
} from '@src/util/conversionFunctionUtil.ts'
import ObjectUtil from '@src/util/lang/object.ts';
import { findComponentDownward } from '@src/util/assist'

import { bindCustomer } from '@src/api/ProductV2Api'
// 关联项类型
const RELATION_TYPE_MAP = {
  customer: 'relationCustomer'
}
export default {
  name: 'customer-bind',
  inject:['initData'],
  props: {
    /* 字段列表 */
    fields: {
      type: Array,
      default: () => [],
    },
    selectedIds:{
      type: Array,
      default: () => [],
    }
  },
  data: () => {
    return {
      // 客户初始化数据
      customerInitData: {},
      addCustomerDialog:false,
      isCreateCustomer:false, //是否创建客户
      value: [],
      init:false,
      pending: false,
      bindDialog: false,
    }
  },
  computed: {
    /** 
     * @description 是否允许新建客户
    */
    allowCreateCustomer() {
      return this.initData?.loginUser?.authorities?.CUSTOMER_CREATE
    },
    // 是否有新建联系人权限
    allowCreateLinkman() {
      return this.initData?.loginUser?.authorities?.LINKMAN_ADD
    },
     /* 关联客户表单单显示字段 */
    bindFormFields() {
      return this.fields.filter(field => field.formType === 'customer');
    },
    /* 客户字段 */
    customerField() {
      return this.fields.filter((f) => f.fieldName === 'customer')[0]
    },
      /* 客户字段配置 */
    customerOption(){
        return (this.customerField.setting && this.customerField.setting.customerOption) || {} ;
    },
        // 选择的客户值
    selectedCustomer(){
        return (this.value.customer && this.value.customer[0]) || {};
    },
    customerFormDom() {
        return this?.customerFormView?.$refs?.CustomerCreateView || {};
    },
  },
  mounted(){
    this.$eventBus.$on('product_create_or_edit.update_linkman', this.updateLinkman);
    this.$eventBus.$on('product_create_or_edit.update_address', this.addAddressCallback);
  },
   beforeDestroy() {
    this.$eventBus.$off('product_create_or_edit.update_linkman', this.updateLinkman);
    this.$eventBus.$off('product_create_or_edit.update_address', this.addAddressCallback);
  },
  methods: {
    ...methods.fetch,
    ...methods.render,
    ...methods.search,
    ...methods.update,
    reset() {
      this.value={}
      this.init=false
    },
    open() {
      this.bindDialog = true
      this.init=true
    },
    sumbit(){
      let params={
        productIds:this.initData?.product?.id?[this.initData?.product?.id]:this.selectedIds || [],
        customerId:this.value['customer'][0].id,
        linkman:{id:this.value['linkman'][0]?.id},
        address:{id:this.value['address'][0]?.id},
      }
      bindCustomer(params).then(res=>{
        if(res.code===0){
          this.bindDialog=false
          this.$emit('refresh')
          this.$platform.notification({
              title: this.$t('common.base.tip.concatSuccess'),
              type: 'success',
            });
        }else{
          this.$platform.alert(res.message);
        }
      })
    },
       /** 
     * @description 更新客户信息
     * @param {Array<Object>} value 客户数据
     * @param {Object} options 配置
    */
   async updateCustomer(value = [], options = {
      isForceUpdateCustomer: false,
      isUpdateCustomerProduct: true
    }) {
      let { isForceUpdateCustomer, isUpdateCustomerProduct } = options;
      let selectedCustomer = value?.[0] || {};
      let currentCustomerId = this.selectedCustomer?.id || this.selectedCustomer?.value;
      let selectedCustomerId = selectedCustomer?.id || selectedCustomer?.value || '';
      
      // 更新客户数据
      this.updateCustomerValue(value.slice());
      
      // 判断选中的客户是否与当前客户数据一致
      if(currentCustomerId == selectedCustomerId && !isForceUpdateCustomer) return
      
      try {
        const result = await this.fetchTaskDefaultInfo({ customerId: selectedCustomerId });
        let { linkman, address } = result;
        
        // 重置联系人和地址
        this.updateLinkmanValue([]);
        this.updateAddressValue([]);
        
        // 绑定联系人和地址
        linkman && this.bindLinkman(linkman);
        address && this.bindAddress(address);
        
      } catch (error) {
        console.warn('task-edit-form: updateCustomer -> error', error);
      }
        
      // 查询客户关联字段
      this.relationFieldSelectHandler();
    },
        /** 
     * @description 更新联系人信息
    */
    async updateLinkman(linkman = {}) {
      if (ObjectUtil.isEmpty(linkman)) {
        return console.warn('Caused: linkman is not object or is empty')
      }
      
      let isHaveCustomer = this.value.customer && this.value.customer.length;
      let linkmanCustomer = linkman?.customer || {};
      
      try {
        // 判断客户是否存在
        if (!isHaveCustomer) {
          // 客户不存在时则下拉框隐藏
          findComponentDownward(this.$refs.linkman, 'base-select').close();
        
          const customerData = [{
            label: linkmanCustomer.name,
            value: linkmanCustomer.id,
            id: linkmanCustomer.id
          }];
          
          // 设置客户数据
          this.updateCustomerValue(customerData);
          // 更新客户信息
          await this.updateCustomer(customerData);
        }
        
        // 绑定联系人数据
        this.bindLinkman(linkman);
        const addressResult = await this.fetchLmBindAddress({ lmId: linkman.id });
        // 如果存在地址信息则绑定地址
        addressResult.data.id && this.bindAddress(addressResult.data);
        
      } catch (error) {
        console.warn('task-edit-form: updateLinkman -> error', error);
      }
    
    },
        /** 
     * @description 关联显示项字段选择处理
     * @param {string} type customer/product
    */
    async relationFieldSelectHandler(type = TaskFieldNameMappingEnum.Customer) {
      let relationFields = this.relationFieldsFilter(type)
      if (relationFields.length <= 0) return

      let productIds = [];
      try {
        let params = {
          customerId: this.selectedCustomer?.value || '',
          productIds
        }
        let res = await this.fetchRelatedInfo(params);
        let isSuccess = res.success;

        if (isSuccess) {
          let result = res.result || {};
          let { customerInfo, relateCustomerFields } = result;
          let isCustomerRelation = type == TaskFieldNameMappingEnum.Customer;

          this.relationFieldUpdateHandler(
            customerInfo,
            relationFields,
            relateCustomerFields,
            isCustomerRelation
          );

        } else {
          this.$platform.alert(res.message);
        }

      } catch (error) {
        console.warn('relationFieldSelectHandler -> error', error)
      }

    },
       /** 
     * @description 关联显示项字段更新处理
    */
    relationFieldUpdateHandler(info, relationFields = [], customerOrPorductFields = [], isCustomerRelation = true) {
      let fieldName = '';
      let formType = '';
      let fieldValue = '';

      relationFields.forEach(relationField => {
        fieldName = relationField?.setting?.fieldName;
        formType = relationField?.setting?.formType;

        if (isCustomerRelation) {
          fieldValue = getFieldValue2string(info, fieldName, formType, customerOrPorductFields, isCustomerRelation);
        } else {
          fieldValue = [];
          
          if (Array.isArray(info)) {
            info.map(item => {
              fieldValue.push(getFieldValue2string(item, fieldName, formType, customerOrPorductFields, isCustomerRelation));
            })
          }
        }

        this.update({ field: relationField, newValue: fieldValue });
      })

    },
   relationFieldsFilter(type = TaskFieldNameMappingEnum.Customer) {
      let relationFields = [];

      // 判断类型是否存在
      let types = [TaskFieldNameMappingEnum.Customer];
      if(types.indexOf(type) < 0) {
        console.warn(`Caused: relationFieldHandler params.type is not in ${types}`);
        return relationFields;
      }
      
      // 判断对应类型的关联显示项字段是否存在
      let formType = RELATION_TYPE_MAP[type];
      relationFields = this.fields.filter(field => field.formType == formType);
      if(relationFields.length <= 0) {
        console.warn(`Caused: this.fields not have ${formType} field`);
      }

      return relationFields;
    },
    /** 
     * @description 绑定联系人
     * @param {Object} linkman 联系人数据
    */
    bindLinkman(linkman = {}) {
      this.updateLinkmanValue([linkmanSelectConversion(linkman)])
    },

    /** 
     * @description 新增地址成功后触发
     * @param {Object} address 地址数据
    */
    addAddressCallback(address = {}) {
      // 获取列表数据
      this.$refs.bizRemoteSelectAddress.search()
      this.bindAddress(address)
    },
    /** 
     * @description 绑定地址
     * @param {Object} address 地址数据
    */
    bindAddress(address = {}) {
      this.updateAddressValue([customerAddressSelectConversion(address)])
    },
    convertCustomerOfSelect(customer = {}) {
      let customerCloneData = _.cloneDeep(customer)
      customerCloneData.id = (customer.id || customer.value || '')

      return customerCloneData
    },
        /** 
     * @description 打开弹窗
     * @param {String} 动作 address/contact/customer/product 
    */
    async dialogOpen(action) {
      let { id, value } = this.selectedCustomer;
      let customerId = id || value;

      if (!customerId && action != TaskFieldNameMappingEnum.Customer) {
        this.$platform.alert(this.$t('product.component.customerBind.tip1'));
        return;
      }

      switch (action) {
      case 'address': {
        this.$refs.EditAddressDialog.openDialog();
        break;
      }
      case 'contact': {
        this.$refs.EditContactDialog.openDialog();
        break;
      }
      case 'customer': {
        this.openCustomerDialogHandler();
        break;
      }
      default: {
        break;
      }
      }
    },
     /** 
     * @description 打开客户弹窗处理
    */
    async openCustomerDialogHandler() {
      try {
        // 打开客户弹窗前，判断是否存在客户初始化数据
        let isHaveCustomerInitData = Object.keys(this.customerInitData) > 0;
        if(!isHaveCustomerInitData) {
          this.loading = true;
          await this.fetchCustomerData();
        }
        
        this.addCustomerDialog = true;
        this.customerFormDom.init = true;

      } catch (error) {
        this.$platform.alert(this.$t('common.base.tip.pleaseTryAgainLater'));
        console.warn('openCustomerDialogHandler -> error', error)
      } finally {
        this.loading = false;
      }
    },
       /** 
     * @description 添加客户 提交
    */
    addCustomerSubmit() {
      // 提交
      this.customerFormDom.submit(data => {
        this.isCreateCustomer = true;
        
        // 绑定客户
        this.updateCustomerValue([{
          label: data.name,
          value: data.id,
          id: data.id
        }])
        
        // 绑定联系人
        this.bindLinkman({
          id: data.lmId,
          name: data.lmName,
          phone: data.lmPhone
        })
        
        // 绑定地址
        data.addressId && this.bindAddress({
          id: data.addressId,
          country: data.country,
          province: data.province,
          city: data.city,
          dist: data.dist,
          address: data.address,
          latitude: data.latitude,
          longitude: data.longitude,
        })
        
        // 查询客户关联字段
        this.relationFieldSelectHandler();
        // 关闭弹窗
        this.addCustomerDialog = false;
        
      });
    },
        /**
     * @description 关闭弹窗
     * @param {String} 动作 customer/product 
    */
    dislogClose(action = '') {
      switch (action) {
      case 'customer': {
        this.customerFormDom.initFormData();
        this.customerFormDom.init = false;
        break;
      }
      default: {
        break;
      }
      }
    },

       /** 
     * @description 搜索联系人 外层处理器
     * @param {Object} params 搜索参数
    */
    async searchLinkmanOuterHandler(params = {}) {
      let customerId = this.selectedCustomer?.value || '';
      params.customerId = this.selectedCustomer?.value || '';
      
      return customerId ? this.searchLinkman(params) : this.searchCustomerByPhone(params);
    },
        /** 
     * @description 搜索地址 外层处理器
     * @param {Object} params 搜索参数
    */
    async searchAddressOuterHandler(params = {}) {
      let { id, value } = this.selectedCustomer;
      params.customerId = id || value;
      return this.searchAddress(params);
    },
  },
  components: {
    [EditAddressDialog.name]: EditAddressDialog,
    [EditContactDialog.name]: EditContactDialog
  }
}
</script>

<style lang="scss" scoped>
.customer-template-option {
  * {
    margin: 0;
  }
  padding: 10px 0;
  h3 {
    font-size: 14px;
    font-weight: 500;
    line-height: 24px;
  }
  
  p {
    display: flex;
    justify-content: space-between;
    line-height: 24px;
    flex-wrap: wrap;
    flex-flow: column;
    
    & > span {
      width: 100%;
      display: flex;
      justify-content: flex-start;
      flex: 1;
      font-size: 12px;
      color: #666666;
      padding-right: 10px;
      
      & > label {
        padding: 0;
        width: 70px;
        max-width: 70px;
      }
    }
  }
}

.customer-template-option {
  p {
    span {
      label {
        width: 40px;
      }
    }
  }
}

.customer-bind-dialog {
  .el-select .el-select__tags > span {
    display: contents;
  }

  .input-and-btn {
    display: flex;
    button {
      margin-left: 10px;
      margin-right: 0px;
    }
  }

  .base-modal-body {
    padding: 10px 30px 0;
  }

  .el-form-item {
    margin: 0;
  }
  .el-radio {
    line-height: 32px;
  }

  .el-select {
    width: 100%;
  }

  .content-item {
    .el-form-item__content {
      max-height: 200px;
      overflow-y: auto;
      word-break: break-all;
    }
  }

  .dialog-footer {
    display: flex;
    justify-content: flex-end;

    span:focus {
      outline: none;
    }

    .iconfont {
      line-height: 32px;
      margin-right: 10px;
      @include fontColor();
    }
  }
}

.base-modal-mask{
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.15);
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 999;
    overflow: auto;
}
</style>
